package com.wing.cabinet.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.cabinet.dao.StorageInventorySpaceDao;
import com.wing.cabinet.model.entity.StorageInventorySpace;
import com.wing.cabinet.model.request.StorageInventorySpaceForm;
import com.wing.cabinet.model.request.UseInventoryInoutDetailForm;
import com.wing.cabinet.model.response.*;
import com.wing.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 暂存柜产品货道库存-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class StorageInventorySpaceServiceImpl extends ServiceImpl<StorageInventorySpaceDao, StorageInventorySpace> implements StorageInventorySpaceService {

    @Override
    public int add(StorageInventorySpaceForm storageInventorySpaceForm) {

        //校验

        StorageInventorySpace storageInventorySpace =new StorageInventorySpace();
        CopyOptions copyOptions = CopyOptions.create()
        .setEditable(StorageInventorySpace.class)
        .setIgnoreError(true)
        .setIgnoreNullValue(true);
        BeanUtil.copyProperties(storageInventorySpaceForm, storageInventorySpace, copyOptions);

        return baseMapper.insert(storageInventorySpace);
    }

    @Override
    public List<StorageInventorySpaceVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<StorageInventorySpaceVO> pageList4app(Page page, Map<String, Object> params) {
        List<StorageInventorySpaceVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public Page<StorageInventorySpaceVO> pageList(Page page, Map<String, Object> params) {
        List<StorageInventorySpaceVO> list = baseMapper.list(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public Page<StorageInventorySpaceVO> storageInventorySpaceList(Page page, Map<String, Object> params) {
        List<StorageInventorySpaceVO> list = baseMapper.storageInventorySpaceList(page, params);
        for(StorageInventorySpaceVO item : list){
            LambdaQueryWrapper<StorageInventorySpace> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StorageInventorySpace ::getCabCode,item.getCabCode());
            wrapper.eq(StorageInventorySpace::getSpaceCode,item.getSpaceCode());
            Integer count = baseMapper.selectCount(wrapper);
            item.setSkuNum(count);
        }
        page.setRecords(list);
        return page;
    }

    @Override
    public Page<StorageInventorySpaceVO> detasPageList(Page page, Map<String, Object> params) {
        List<StorageInventorySpaceVO> list = baseMapper.detasList(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public StorageInventorySpaceVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }

    @Override
    public List<StorageInventorySpaceVO> ecxportList(Map<String, Object> params) {
        return baseMapper.detasList(null,params);
    }

    @Override
    public List<CabOptimalSpaces> getCabOptimalSpaces(UseInventoryInoutDetailForm useInventoryInoutDetailForm) {
        this.getOptimalSpaces(useInventoryInoutDetailForm);
        List<UseInventoryInoutDetailForm> skuLaneList=useInventoryInoutDetailForm.getDetailList();

//        Map<String,List<CellInventorySpaceVO>> resultMap=new HashMap<>();
//        Map<String,List<Integer>> cabSpaceCodeMap=new LinkedHashMap<>();
//        Map<String,CabQuantityVO> cabCodeQuantityMap=new HashMap<>();
//        for (UseInventoryInoutDetailForm item:skuLaneList){
//            for (CellInventorySpaceVO cellInventorySpace:item.getResultLaneList()){
//                Integer spaceCodeKey=Integer.valueOf(cellInventorySpace.getSpaceCode())/10;
//                String cabCode=cellInventorySpace.getCabCode();
//                String key=cabCode+"_"+spaceCodeKey;
//                List<CellInventorySpaceVO> tempList=resultMap.get(key);
//
//                if (tempList!=null){
//                    tempList.add(cellInventorySpace);
//                }else{
//                    tempList=new ArrayList<>();
//                    tempList.add(cellInventorySpace);
//                    resultMap.put(key,tempList);
//                }
//                CabQuantityVO cabQuantityVO=cabCodeQuantityMap.get(cabCode);
//                if (cabQuantityVO==null){
//                    cabQuantityVO=new CabQuantityVO();
//                    cabQuantityVO.setCabCode(cabCode);
//                    cabQuantityVO.setQuantity(cellInventorySpace.getQuantity());
//                    cabCodeQuantityMap.put(cabCode,cabQuantityVO);
//                }else{
//                    cabQuantityVO.setQuantity(cabQuantityVO.getQuantity()+cellInventorySpace.getQuantity());
//                    cabCodeQuantityMap.put(cabCode,cabQuantityVO);
//                }
//                List<Integer> spaceCodeList=cabSpaceCodeMap.get(cabCode);
//                if (spaceCodeList!=null){
//                    if (!spaceCodeList.contains(spaceCodeKey)){
//                        spaceCodeList.add(spaceCodeKey);
//                    }
//                }else{
//                    spaceCodeList=new ArrayList<>();
//                    spaceCodeList.add(spaceCodeKey);
//                    cabSpaceCodeMap.put(cabCode,spaceCodeList);
//                }
//            }
//        }
//        List<CabOptimalSpaces> resultList=new ArrayList<>();
//        /**
//        resultMap.keySet().forEach(e->{
//            CabOptimalSpaces cabOptimalSpaces=new CabOptimalSpaces();
//            cabOptimalSpaces.setCabCode(e);
//
//            Map<Integer,List<CellInventorySpaceVO>> spaceMap=new HashMap<>();
//            List<Integer> spaceCodeKeyList=new ArrayList<>();
//            for (CellInventorySpaceVO cellInventorySpaceVO:resultMap.get(e)){
//                Integer spaceCodeKey=Integer.valueOf(cellInventorySpaceVO.getSpaceCode())/10;
//                List<CellInventorySpaceVO> tempList=spaceMap.get(spaceCodeKey);
//                if (tempList!=null){
//                    tempList.add(cellInventorySpaceVO);
//                }else{
//                   tempList=new ArrayList<>();
//                   tempList.add(cellInventorySpaceVO);
//                   spaceMap.put(spaceCodeKey,tempList);
//                }
//            }
//            Collections.sort(spaceCodeKeyList);
//            List<CellInventorySpaceVO> resultLaneList=new ArrayList<>();
//            for (Integer spaceCodeKey:spaceCodeKeyList){
//                resultLaneList.addAll(spaceMap.get(spaceCodeKey));
//            }
//            cabOptimalSpaces.setResultLaneList(resultLaneList);
//
//            resultList.add(cabOptimalSpaces);
//        });
//         */
//        List<CabQuantityVO> cabQuantityList=new ArrayList<>();
//        cabCodeQuantityMap.forEach((key,val)->{
//            cabQuantityList.add(val);
//        });
//        Collections.sort(cabQuantityList);
//        cabQuantityList.forEach(e->{
//            String cabCode=e.getCabCode();
//            List<Integer> spaceCodeKyList=cabSpaceCodeMap.get(cabCode);
//            CabOptimalSpaces cabOptimalSpaces=new CabOptimalSpaces();
//            cabOptimalSpaces.setCabCode(cabCode);
//            Collections.sort(spaceCodeKyList);
//            List<CellInventorySpaceVO> resultLaneList=new ArrayList<>();
//            spaceCodeKyList.forEach(spaceCodeKey->{
//                resultLaneList.addAll(resultMap.get(cabCode+"_"+spaceCodeKey));
//            });
//            cabOptimalSpaces.setResultLaneList(resultLaneList);
//            resultList.add(cabOptimalSpaces);
//        });
        List<CabOptimalSpaces> resultList=sortSpaces(skuLaneList);
        return resultList;
    }

    @Override
    public List<CabOptimalSpaces> getCabOptimalCargoSpaces(UseInventoryInoutDetailForm useInventoryInoutDetailForm) {
        this.getOptimalCargoSpaces(useInventoryInoutDetailForm);
        List<UseInventoryInoutDetailForm> skuLaneList=useInventoryInoutDetailForm.getDetailList();
        List<CabOptimalSpaces> resultList=sortSpaces(skuLaneList);
        return resultList;
    }

    public List<CabOptimalSpaces> sortSpaces(List<UseInventoryInoutDetailForm> skuLaneList){
        Map<String,List<StorageInventorySpaceVO>> resultMap=new HashMap<>();
        Map<String,List<Integer>> cabSpaceCodeMap=new LinkedHashMap<>();
        Map<String, CabQuantityVO> cabCodeQuantityMap=new HashMap<>();
        for (UseInventoryInoutDetailForm item:skuLaneList){
            for (StorageInventorySpaceVO cellInventorySpace:item.getResultStorageSpaceList()){
                Integer spaceCodeKey=Integer.valueOf(cellInventorySpace.getSpaceCode())/10;
                String cabCode=cellInventorySpace.getCabCode();
                String key=cabCode+"_"+spaceCodeKey;
                List<StorageInventorySpaceVO> tempList=resultMap.get(key);

                if (tempList!=null){
                    tempList.add(cellInventorySpace);
                }else{
                    tempList=new ArrayList<>();
                    tempList.add(cellInventorySpace);
                    resultMap.put(key,tempList);
                }
                CabQuantityVO cabQuantityVO=cabCodeQuantityMap.get(cabCode);
                if (cabQuantityVO==null){
                    cabQuantityVO=new CabQuantityVO();
                    cabQuantityVO.setCabCode(cabCode);
                    cabQuantityVO.setQuantity(cellInventorySpace.getQuantity());
                    cabCodeQuantityMap.put(cabCode,cabQuantityVO);
                }else{
                    cabQuantityVO.setQuantity(cabQuantityVO.getQuantity()+cellInventorySpace.getQuantity());
                    cabCodeQuantityMap.put(cabCode,cabQuantityVO);
                }
                List<Integer> spaceCodeList=cabSpaceCodeMap.get(cabCode);
                if (spaceCodeList!=null){
                    if (!spaceCodeList.contains(spaceCodeKey)){
                        spaceCodeList.add(spaceCodeKey);
                    }
                }else{
                    spaceCodeList=new ArrayList<>();
                    spaceCodeList.add(spaceCodeKey);
                    cabSpaceCodeMap.put(cabCode,spaceCodeList);
                }
            }
        }
        List<CabOptimalSpaces> resultList=new ArrayList<>();
        /**
         resultMap.keySet().forEach(e->{
         CabOptimalSpaces cabOptimalSpaces=new CabOptimalSpaces();
         cabOptimalSpaces.setCabCode(e);

         Map<Integer,List<CellInventorySpaceVO>> spaceMap=new HashMap<>();
         List<Integer> spaceCodeKeyList=new ArrayList<>();
         for (CellInventorySpaceVO cellInventorySpaceVO:resultMap.get(e)){
         Integer spaceCodeKey=Integer.valueOf(cellInventorySpaceVO.getSpaceCode())/10;
         List<CellInventorySpaceVO> tempList=spaceMap.get(spaceCodeKey);
         if (tempList!=null){
         tempList.add(cellInventorySpaceVO);
         }else{
         tempList=new ArrayList<>();
         tempList.add(cellInventorySpaceVO);
         spaceMap.put(spaceCodeKey,tempList);
         }
         }
         Collections.sort(spaceCodeKeyList);
         List<CellInventorySpaceVO> resultLaneList=new ArrayList<>();
         for (Integer spaceCodeKey:spaceCodeKeyList){
         resultLaneList.addAll(spaceMap.get(spaceCodeKey));
         }
         cabOptimalSpaces.setResultLaneList(resultLaneList);

         resultList.add(cabOptimalSpaces);
         });
         */
        List<CabQuantityVO> cabQuantityList=new ArrayList<>();
        cabCodeQuantityMap.forEach((key,val)->{
            cabQuantityList.add(val);
        });
        Collections.sort(cabQuantityList);
        cabQuantityList.forEach(e->{
            String cabCode=e.getCabCode();
            List<Integer> spaceCodeKyList=cabSpaceCodeMap.get(cabCode);
            CabOptimalSpaces cabOptimalSpaces=new CabOptimalSpaces();
            cabOptimalSpaces.setCabCode(cabCode);
            Collections.sort(spaceCodeKyList);
            List<StorageInventorySpaceVO> resultLaneList=new ArrayList<>();
            spaceCodeKyList.forEach(spaceCodeKey->{
                resultLaneList.addAll(resultMap.get(cabCode+"_"+spaceCodeKey));
            });
            cabOptimalSpaces.setResultStorageSpaceList(resultLaneList);
            resultList.add(cabOptimalSpaces);
        });
        return resultList;
    }

    @Override
    public void getOptimalSpaces(UseInventoryInoutDetailForm useInventoryInoutDetailForm) {
//        SystemRuleInfo systemRuleInfo=systemRuleInfoService.getOne(new QueryWrapper<SystemRuleInfo>());
//        SystemRuleInfo systemRuleInfo=systemRuleInfoService.getRuleInfo();
//        Boolean outOrderFlag=true;
//        if (systemRuleInfo!=null){
//            outOrderFlag=systemRuleInfo.getOutOrderFlag();
//        }
        Boolean hasTargetQuantity=true;
        Boolean isEmpty=true;
        useInventoryInoutDetailForm.setIsEmpty(isEmpty);
        Map paramMap=new HashMap();
        String[] cabCodes=useInventoryInoutDetailForm.getCabCode().split(",");
        for (UseInventoryInoutDetailForm item:useInventoryInoutDetailForm.getDetailList()){
            paramMap.put("skuCode4app",item.getSkuCode());
            paramMap.put("cabCodes",cabCodes);
            paramMap.put("quantityPackUnit",item.getQuantityPackUnit());
            paramMap.put("sort","asc");
//                paramMap.put("quantity4Query",item.getQuantity());
            List<StorageInventorySpaceVO> cellInventorySpaceVOS=baseMapper.listOptimalSpace4app(paramMap);
            if (cellInventorySpaceVOS.size()==0
//                    ||getSumQuantity(cellInventorySpaceVOS)<item.getQuantity()
            ){
//                throw new BusinessException("SKU["+item.getSkuCode()+"]货不足");
                continue;
            }
            isEmpty=false;
            item.setQuantityTarget(item.getQuantity());
            useInventoryInoutDetailForm.getQuantityTargetList().add(item.getQuantityTarget());
            item.setQuantityExist(getSumQuantity(cellInventorySpaceVOS));
            useInventoryInoutDetailForm.getQuantityExistList().add(item.getQuantityExist());
            item.setQuantityBySpace(item.getQuantityExist());
            item.setQuantitySurplus(item.getQuantityTarget()-item.getQuantityExist());

            useInventoryInoutDetailForm.getQuantitySurplusList().add(item.getQuantitySurplus());

            if (item.getQuantityExist()<item.getQuantity()){
                item.setQuantity(item.getQuantityExist());
            }
            if (item.getQuantitySurplus()>0){
                hasTargetQuantity=false;
            }
            item.setStorageSpaceList(cellInventorySpaceVOS);

            Map<String,List<StorageInventorySpaceVO>> spaceMap= getAvaiableCab(item.getStorageSpaceList(),item.getQuantity());
            item.setCabStorageSpacesMap(spaceMap);
            item.setCabCodesSet(spaceMap.keySet());
        }
        if (isEmpty){
            useInventoryInoutDetailForm.setIsEmpty(isEmpty);
            useInventoryInoutDetailForm.setHasTargetQuantity(false);
            return;
        }
        String optimalCabCode=getOptimalCab(useInventoryInoutDetailForm.getDetailList());
        for (UseInventoryInoutDetailForm item:useInventoryInoutDetailForm.getDetailList()){
            if (item.getCabStorageSpacesMap().containsKey(optimalCabCode)){
                List<StorageInventorySpaceVO> sortList=item.getCabStorageSpacesMap().get(optimalCabCode);
                Collections.sort(sortList);
                item.setResultStorageSpaceList(sortList);
            }else{
                if (item.getCabCodesSet().size()>0){
                    List<StorageInventorySpaceVO> sortList=item.getCabStorageSpacesMap().get(item.getCabCodesSet().iterator().next());
                    Collections.sort(sortList);
                    item.setResultStorageSpaceList(sortList);
                }else{
                    item.setResultStorageSpaceList(item.getStorageSpaceList());
                    List<CabSortInventorySpaceVO> sortList=getCabSpaces(item.getStorageSpaceList());
                    Collections.sort(sortList);
                    item.setSortCabList(sortList);
                }

            }
            item.setResultStorageSpaceList(getSpaceByLanePullFull(item));
        }
        Map errerMap=new HashMap();
        useInventoryInoutDetailForm.getDetailList().forEach(e->{
            e.setLaneList(null);
            e.setCabSpacesMap(null);
            e.setCabCodesSet(null);
            e.setSortCabList(null);
            //test
            e.setQuantityResult(getSumQuantity(e.getResultStorageSpaceList()));
            if (!e.getQuantity().equals(e.getQuantityResult())){
//                log.error("get optimal space fail:{}","SKU["+e.getSkuCode()+"]分配的领新数量不够");
//                throw new BusinessException("SKU["+e.getSkuCode()+"]分配的领新数量不够");
                errerMap.put(e.getSkuCode(),e);
            }

        });
        if (errerMap.size()>0){
//            return null;
        }
        useInventoryInoutDetailForm.setIsEmpty(isEmpty);
        useInventoryInoutDetailForm.setHasTargetQuantity(hasTargetQuantity);
//        return useInventoryInoutDetailForm.getDetailList();
    }


     void getOptimalCargoSpaces(UseInventoryInoutDetailForm useInventoryInoutDetailForm) {
//        SystemRuleInfo systemRuleInfo=systemRuleInfoService.getOne(new QueryWrapper<SystemRuleInfo>());
//        SystemRuleInfo systemRuleInfo=systemRuleInfoService.getRuleInfo();
//        Boolean outOrderFlag=true;
//        if (systemRuleInfo!=null){
//            outOrderFlag=systemRuleInfo.getOutOrderFlag();
//        }
        Boolean hasTargetQuantity=true;
        Map paramMap=new HashMap();
        String[] cabCodes=useInventoryInoutDetailForm.getCabCode().split(",");
        for (UseInventoryInoutDetailForm item:useInventoryInoutDetailForm.getDetailList()){
            paramMap.put("skuCode4app",item.getSkuCode());
            paramMap.put("cabCodes",cabCodes);
            paramMap.put("quantityPackUnit",item.getQuantityPackUnit());
            paramMap.put("sort","asc");
//                paramMap.put("quantity4Query",item.getQuantity());
            List<StorageInventorySpaceVO> cellInventorySpaceVOS=baseMapper.listOptimalSpace4app(paramMap);
            if (cellInventorySpaceVOS.size()==0||getSumQuantity(cellInventorySpaceVOS)<item.getQuantity()){
                throw new BusinessException("SKU["+item.getSkuCode()+"]货不足");
//                return null;
            }
            item.setQuantityTarget(item.getQuantity());
            useInventoryInoutDetailForm.getQuantityTargetList().add(item.getQuantityTarget());
            item.setQuantityExist(getSumQuantity(cellInventorySpaceVOS));
            useInventoryInoutDetailForm.getQuantityExistList().add(item.getQuantityExist());
            item.setQuantityBySpace(item.getQuantityExist());
            item.setQuantitySurplus(item.getQuantityTarget()-item.getQuantityExist());

            useInventoryInoutDetailForm.getQuantitySurplusList().add(item.getQuantitySurplus());

            if (item.getQuantityExist()<item.getQuantity()){
                item.setQuantity(item.getQuantityExist());
            }
            if (item.getQuantitySurplus()>0){
                hasTargetQuantity=false;
            }
            item.setStorageSpaceList(cellInventorySpaceVOS);

            Map<String,List<StorageInventorySpaceVO>> spaceMap= getAvaiableCab(item.getStorageSpaceList(),item.getQuantity());
            //item.setCabStorageSpacesMap(spaceMap);
            if(null != spaceMap) {
                item.setCabStorageSpacesMap(spaceMap);
            }else{
                item.setCabStorageSpacesMap(new HashMap<String,List<StorageInventorySpaceVO>>());
            }
            //item.setCabCodesSet(spaceMap.keySet());
            if(null != spaceMap.keySet()) {
                item.setCabCodesSet(spaceMap.keySet());
            }else{
                item.setCabCodesSet(new HashSet<>());
            }
        }

        String optimalCabCode=getOptimalCab(useInventoryInoutDetailForm.getDetailList());
        for (UseInventoryInoutDetailForm item:useInventoryInoutDetailForm.getDetailList()){
            if (item.getCabStorageSpacesMap().containsKey(optimalCabCode)){
                List<StorageInventorySpaceVO> sortList=item.getCabStorageSpacesMap().get(optimalCabCode);
                Collections.sort(sortList);
                item.setResultStorageSpaceList(sortList);
            }else{
                if (item.getCabCodesSet().size()>0){
                    List<StorageInventorySpaceVO> sortList=item.getCabStorageSpacesMap().get(item.getCabCodesSet().iterator().next());
                    Collections.sort(sortList);
                    item.setResultStorageSpaceList(sortList);
                }else{
                    item.setResultStorageSpaceList(item.getStorageSpaceList());
                    List<CabSortInventorySpaceVO> sortList=getCabSpaces(item.getStorageSpaceList());
                    Collections.sort(sortList);
                    item.setSortCabList(sortList);
                }

            }
            item.setResultStorageSpaceList(getSpaceByLanePullFull(item));
        }
        Map errerMap=new HashMap();
        useInventoryInoutDetailForm.getDetailList().forEach(e->{
            e.setLaneList(null);
            e.setCabSpacesMap(null);
            e.setCabCodesSet(null);
            e.setSortCabList(null);
            //test
            e.setQuantityResult(getSumQuantity(e.getResultStorageSpaceList()));
            if (!e.getQuantity().equals(e.getQuantityResult())){
                log.error("get optimal space fail:{}","SKU["+e.getSkuCode()+"]分配的领新数量不够");
                throw new BusinessException("SKU["+e.getSkuCode()+"]分配的领新数量不够");
//                errerMap.put(e.getSkuCode(),e);
            }

        });
        if (errerMap.size()>0){
//            return null;
        }
        useInventoryInoutDetailForm.setHasTargetQuantity(hasTargetQuantity);
//        return useInventoryInoutDetailForm.getDetailList();
    }


    private List<StorageInventorySpaceVO> getSpaceByLanePullFull(UseInventoryInoutDetailForm useInventoryInoutDetailForm){

        List<StorageInventorySpaceVO> spaceList=new ArrayList<>();
        Integer quantity=useInventoryInoutDetailForm.getQuantity();
        if (CollectionUtil.isNotEmpty(useInventoryInoutDetailForm.getSortCabList())){
            L1:for (int i=0;i<useInventoryInoutDetailForm.getSortCabList().size();i++){
                CabSortInventorySpaceVO cabSortInventorySpaceVO=useInventoryInoutDetailForm.getSortCabList().get(i);
                List<StorageInventorySpaceVO> cabSpaceList= cabSortInventorySpaceVO.getStorageSpaceList();
//                if (i>0){
                Collections.sort(cabSpaceList);
//                }
                for (StorageInventorySpaceVO item:cabSpaceList){
                    if (item.getQuantity()>=quantity){
                        item.setQuantity(quantity);
                        spaceList.add(item);
                        break L1;
                    }else{
                        spaceList.add(item);
                        quantity=quantity-item.getQuantity();
                    }
                }
            }
        }else{
            if (useInventoryInoutDetailForm.getResultStorageSpaceList()!=null){
                for (StorageInventorySpaceVO item:useInventoryInoutDetailForm.getResultStorageSpaceList()){
                    if (item.getQuantity()>=quantity){
                        item.setQuantity(quantity);
                        spaceList.add(item);
                        break;
                    }else{
                        spaceList.add(item);
                        quantity=quantity-item.getQuantity();
                    }
                }
            }

        }

        return spaceList;
    }

    private Integer getSumQuantity(List<StorageInventorySpaceVO> list){
        Integer sum=0;
        for (StorageInventorySpaceVO cellInventorySpaceVO:list){
            sum+=cellInventorySpaceVO.getQuantity();
        }
        return sum;
    }

    private List<CabSortInventorySpaceVO> getCabSpaces(List<StorageInventorySpaceVO> list){
        List<CabSortInventorySpaceVO> sortList=new ArrayList<>();
        if (list.size()==0){
            return sortList;
        }
        Integer sum=0;
        String preCab=list.get(0).getCabCode();
        List<StorageInventorySpaceVO> tempList=new ArrayList<>();
        for (StorageInventorySpaceVO cellInventorySpaceVO:list){
            String nextCab=cellInventorySpaceVO.getCabCode();
            if (preCab.equals(nextCab)){
                sum+=cellInventorySpaceVO.getQuantity();
                tempList.add(cellInventorySpaceVO);
            }else{
                CabSortInventorySpaceVO cabSortInventorySpaceVO=new CabSortInventorySpaceVO();
                cabSortInventorySpaceVO.setQuantity(sum);
                cabSortInventorySpaceVO.setStorageSpaceList(tempList);
                cabSortInventorySpaceVO.setCabCode(preCab);
                sortList.add(cabSortInventorySpaceVO);
                preCab=nextCab;
                sum=cellInventorySpaceVO.getQuantity();
                tempList=new ArrayList<>();
                tempList.add(cellInventorySpaceVO);
            }
        }
        CabSortInventorySpaceVO cabSortInventorySpaceVO=new CabSortInventorySpaceVO();
        cabSortInventorySpaceVO.setQuantity(sum);
        cabSortInventorySpaceVO.setStorageSpaceList(tempList);
        cabSortInventorySpaceVO.setCabCode(preCab);
        sortList.add(cabSortInventorySpaceVO);
        return sortList;
    }

    private Map<String,List<StorageInventorySpaceVO>> getAvaiableCab(List<StorageInventorySpaceVO> list, Integer quantity){
        Map<String,List<StorageInventorySpaceVO>> resultMap=new HashMap<>();
        if (list.size()==0){
            return resultMap;
        }
        Integer sum=0;
        String preCab=list.get(0).getCabCode();
        List<StorageInventorySpaceVO> tempList=new ArrayList<>();
        for (StorageInventorySpaceVO cellInventorySpaceVO:list){
            String nextCab=cellInventorySpaceVO.getCabCode();
            if (preCab.equals(nextCab)){
                sum+=cellInventorySpaceVO.getQuantity();
                tempList.add(cellInventorySpaceVO);
            }else{
                if (sum>=quantity){
                    resultMap.put(preCab,tempList);
                }
                preCab=nextCab;
                sum=cellInventorySpaceVO.getQuantity();
                tempList=new ArrayList<>();
                tempList.add(cellInventorySpaceVO);
            }
        }
        if (sum>=quantity){
            resultMap.put(preCab,tempList);
        }
        return resultMap;
    }

    private String getOptimalCab(List<UseInventoryInoutDetailForm> detailList){
        if (detailList.size()==1){
            if (detailList.get(0).getCabCodesSet()!=null&&detailList.get(0).getCabCodesSet().size()>0){
                Integer quantity=Integer.MAX_VALUE;
                String cabCode=null;
                Iterator<String> iterator=detailList.get(0).getCabCodesSet().iterator();
                while (iterator.hasNext()){
                    String nextCabCode=iterator.next();
                    List<StorageInventorySpaceVO> cellInventorySpaceVOS=detailList.get(0).getCabStorageSpacesMap().get(nextCabCode);
                    Integer nextQuantity=getSumQuantity(cellInventorySpaceVOS);
                    if (nextQuantity<quantity){
                        quantity=nextQuantity;
                        cabCode=nextCabCode;
                    }
                }
                if (cabCode!=null){
                    return cabCode;
                }
            }

        }
        Map<String,Integer> cabCodesMap=new HashMap<>();
        for (UseInventoryInoutDetailForm item:detailList){
            if(null == item.getCabCodesSet()) continue;
            item.getCabCodesSet().forEach(e->{
                if(cabCodesMap.containsKey(e)){
                    cabCodesMap.put(e,cabCodesMap.get(e)+1);
                }else{
                    cabCodesMap.put(e,1);
                }
            });
        }
        Set<String> cabCodeSet=cabCodesMap.keySet();
        Integer maxVal=0;
        String optimalCabCode="";
        for(String cabCode:cabCodeSet){
            Integer val=cabCodesMap.get(cabCode);
            if (val>maxVal){
                optimalCabCode=cabCode;
                maxVal=val;
            }
        }
        return optimalCabCode;
    }

    @Override
    public Integer getSumByParams(String mainCabCode, String cabCode, String skuCode) {
        return baseMapper.getSumByParams(mainCabCode,cabCode,skuCode);
    }
}
